import os, sys

from django.db import models
from django.forms import ModelForm

from django.db import IntegrityError

from django.contrib.auth.models import User, Group

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic


from django.db.models import Sum, Count

from django.conf import settings

from assets.signals import asset_changed

from cache import model_property_cache


from files.models import File
from ratings.models import Rating
from tags.models import TaggedObject

import logging
LOG = logging.getLogger("assets.models")

def _Normalize(path):  
  return path.replace('\\\\', '/').replace('\\', '/')
  
from assets.managers import FormatTypeManager, FormatManager, AssetManager
  
    


class FormatType(models.Model):
  class Meta:
    db_table = 'FormatTypes'
    verbose_name_plural = "Format Types"
  
  name = models.CharField(max_length=255, unique=True) 
  
  objects = FormatTypeManager()
  def natural_key(self):
    return (self.name, )

  def __unicode__(self):
    return self.name
    

class Format(models.Model):
  class Meta:
    db_table = 'Formats'
    verbose_name_plural = "Formats"
  
  name = models.CharField(max_length=255, unique=True) 
  type = models.ForeignKey(FormatType, blank=True, null=True)
  legible = models.CharField(max_length=255, blank=True, null=True) 
  ext = models.CharField(max_length=255, blank=True, null=True) 
  
  objects = FormatManager()
  def natural_key(self):
    return (self.name, self.type.name if self.type else None, )

  def __unicode__(self):
    return str(self.legible) + ' (' + str(self.name) + ') ' + str(self.ext)


class Asset(models.Model):
  objects = AssetManager()
  class Meta:
    db_table = 'Assets'
    verbose_name_plural = "Assets"
    unique_together = (("file", "subName", "format"),)
    
  #uuid = models.CharField(max_length=40, unique=True)
  id = models.CharField(max_length=40, primary_key=True)
  file = models.ForeignKey(File)
  subName = models.CharField(max_length=256)
  format = models.ForeignKey(Format)
  
  dependencies = models.ManyToManyField("self", symmetrical=False, blank=True)
  
  stamp = models.DateTimeField(auto_now=True, auto_now_add=True, db_index=True)
  
  tags = generic.GenericRelation(TaggedObject)
  
  @property
  @model_property_cache
  def avg_rating(self):
    type = ContentType.objects.get_for_model(self)
    rating = Rating.objects.filter(content_type__pk=type.id, object_id=self.id).aggregate(r=Sum('rating'), u=Count('user'))
    return rating['r'] / rating['u']
  
  @property
  def rating_percent(self):
    try:
      return int((self.avg_rating/5.0)*100.0)
    except:
      return 0
  
  @property
  def ancestor(self):
    try:
      return self.file.ancestor.asset_set.get(subName=self.subName,format=self.format)
    except Asset.DoesNotExist:
      return None
    
  @property
  def version(self):
    return self.file.version
  
  @property
  def is_latest(self):
    return self.file.descendants.count() == 0
    
  @property
  def latest(self):
    try:
      return self.file.latest.asset_set.get(subName=self.subName,format=self.format)
    except Asset.DoesNotExist:
      return self
      
  @property
  def descendant(self):
    try:
      return self.file.descendant.asset_set.get(subName=self.subName,format=self.format)
    except Asset.DoesNotExist:
      return None

  @models.permalink
  def get_absolute_url(self):
    return ('webgui.views.asset', [str(self.id)])
  
  @property
  def display_name(self):  
    return 'Asset: %s'%(self.subName)
    
  def __unicode__(self):
    return '[ASSET: %s (%s - %s)(deps: %s)]'%(self.id, self.subName, self.format.name, [dep.id for dep in self.dependencies.all()])


class Collection(models.Model):
  class Meta:
    db_table = 'Collections'
    verbose_name_plural = "Collections"
    unique_together = (("group", "name"),)

  group = models.ForeignKey(Group, blank=True, null=True)
  name = models.CharField(max_length=256)
  assets = models.ManyToManyField(Asset)

  def __unicode__(self):
    return '[%d: %s]'%(self.id, self.name)


class UserCollection(models.Model):
  class Meta:
    db_table = 'UserCollections'
    verbose_name_plural = "User Collections"
    unique_together = (("user", "name"),)

  user = models.ForeignKey(User)
  name = models.CharField(max_length=256)
  assets = models.ManyToManyField(Asset)
  
  stamp = models.DateTimeField(auto_now=True, auto_now_add=True, db_index=True)

  def __unicode__(self):
    return '[%d: %s]'%(self.id, self.name)
    

class Version(models.Model):
  class Meta:
    db_table = 'Versions'
    verbose_name_plural = "Versions"
    unique_together = (("asset", "format", "arguments"),)

  asset = models.ForeignKey(Asset)
  format = models.ForeignKey(Format)
  arguments = models.CharField(max_length=256)
  version = models.IntegerField()

  def __unicode__(self):
    return '[%s: %s: %s  (%s)]'%(self.asset.id, self.format.name, self.version, self.arguments)
    

class MetaData(models.Model):
  class Meta:
    db_table = 'MetaData'
    verbose_name_plural = "MetaData"
    unique_together = (("asset", "name"),)

  asset = models.ForeignKey(Asset)
  name = models.CharField(max_length=256)
  type = models.CharField(max_length=40)
  value = models.CharField(max_length=4096)

  def SetValue(self, value):
    x = str(type(value))
    self.type = x[x.find('\'')+1:x.rfind('\'')][:40]
    self.value = value
    
  def __unicode__(self):
    return '(%s) %s : %s'%(str(self.asset.id), self.name, self.value)

    
#register models for jobs    
from modeljobs import *
